// #include "ndoe_config.h"

#include "json_handler.h"
#include <rapidjson/document.h> // 依赖rapidjson库
#include <rapidjson/stringbuffer.h>
#include <rapidjson/prettywriter.h>
#include <rapidjson/istreamwrapper.h>
#include "rapidjson/ostreamwrapper.h"
#include <rapidjson/writer.h>
#include "log/syslog.h"
#include <fstream>

using namespace rapidjson;
using namespace equip_system;

//
#define TAG "CNodeDataCofing"

/*
message = {
        "Services" : [
            {
                "id" : "SG24024 ",
                "Name" : "WY-300LC",
                "properties" : {
                    "工作令号" : "00000000",
                    "X轴偏差" : "32767",
                    "Y轴偏差" : "32767",
                    "T轴偏差" : "32767",
                    "相机1偏差" : "32767",
                    "相机2偏差" : "32767",
                    "产量" : "65535",
                    "故障码" : "65535",
                    "印刷压力" : "70",
                    "印刷次数" : "1",
                    "印刷速度" : "50",
                    "涂墨速度" : "100",
                    "印刷间距" : "2.2",
                    "运行时长" : "20250707",
                    "运行状态" : "1"
                }
            }
        ]
    }
*/
std::string CNodeDataCofing::serialize(const NodeData_Config &data, vector<std::string> &param)
{
    // 创建JSON文档
    rapidjson::Document doc;
    doc.SetObject();
    rapidjson::Document::AllocatorType &alloc = doc.GetAllocator();

    // 创建Services数组
    rapidjson::Value services(rapidjson::kArrayType);

    // 创建Service对象
    rapidjson::Value service(rapidjson::kObjectType);

    // 添加id和Name字段
    service.AddMember(
        rapidjson::Value("id", alloc).Move(),
        rapidjson::Value(data.id.c_str(), alloc).Move(),
        alloc);

    service.AddMember(
        rapidjson::Value("Name", alloc).Move(),
        rapidjson::Value(data.Name.c_str(), alloc).Move(),
        alloc);

    // 创建properties对象
    rapidjson::Value properties(rapidjson::kObjectType);

    // // 添加工作令号（如果列表中没有则手动添加）
    // if (!properties.HasMember(u8"工作令号"))
    // {
    //     if (param.size() > 0)
    //     {
    //         properties.AddMember(
    //             rapidjson::Value(u8"工作令号", alloc).Move(),
    //             rapidjson::Value(u8"00000000", alloc).Move(),
    //             alloc);
    //     }
    //     else
    //     {
    //         properties.AddMember(
    //             rapidjson::Value(u8"工作令号", alloc).Move(),
    //             rapidjson::Value(param[0].c_str(), alloc).Move(),
    //             alloc);
    //     }
    // }
    // 遍历EquipProperty列表，填充properties
    for (typename std::vector<EquipProperty>::const_iterator it = data.list.begin();
         it != data.list.end(); ++it)
    {
        const EquipProperty &prop = *it;

        // 使用中文名称作为键（name_cn），值从value向量中取第一个元素
        if (!prop.name_cn.empty() && !prop.value.empty())
        {
            size_t num = prop.value.size();
            if (num > 0)
            {
                /**
                 * 如果是故障码，则将value[]的多个string元素合并为一个string
                 */
                if (prop.name_en == "faultcode")
                {
                    string val;
                    for (int i = 0; i < num; i++)
                    {
                        val.append(prop.value[i]);
                    }
                    properties.AddMember(
                        rapidjson::Value(prop.name_cn.c_str(), alloc).Move(),
                        rapidjson::Value(val.c_str(), alloc).Move(),
                        alloc);
                }
                else
                {
                    properties.AddMember(
                        rapidjson::Value(prop.name_cn.c_str(), alloc).Move(),
                        rapidjson::Value(prop.value[0].c_str(), alloc).Move(),
                        alloc);
                }
            }
        }
    }

    // 将properties添加到service
    service.AddMember(
        rapidjson::Value("properties", alloc).Move(),
        properties,
        alloc);

    // 将service添加到services数组
    services.PushBack(service, alloc);

    // 将services数组添加到根对象
    doc.AddMember(
        rapidjson::Value("Services", alloc).Move(),
        services,
        alloc);

    // 将JSON文档转换为字符串
    rapidjson::StringBuffer buffer;
    rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
    doc.Accept(writer);

    return std::string(buffer.GetString());
    // return "";
}

// CNodeDataCofing 实现
bool CNodeDataCofing::read(const std::string &filename, NodeData_Config &data, string &json_string)
{
    // 打开文件
    std::ifstream ifs(filename);
    if (!ifs.is_open())
    {
        ES_LOG(TAG, LEVEL_ERROR, "Failed to open config file: %s", filename.c_str());
        return false;
    }

    // 解析JSON
    rapidjson::IStreamWrapper isw(ifs);
    rapidjson::Document doc;
    doc.ParseStream(isw);

    // 检查解析错误
    if (doc.HasParseError())
    {
        ES_LOG(TAG, LEVEL_ERROR, "JSON parse error(%d), offset:%d", doc.GetParseError(), doc.GetErrorOffset());
        return false;
    }

    if (!doc.IsObject())
    {
        ES_LOG(TAG, LEVEL_ERROR, "JSON root is not an object");
        return false;
    }

    // 读取顶层字段
    if (doc.HasMember("equip") && doc["equip"].IsString())
    {
        data.equip = doc["equip"].GetString();
    }

    if (doc.HasMember("type") && doc["type"].IsString())
    {
        data.type = doc["type"].GetString();
    }

    if (doc.HasMember("id") && doc["id"].IsString())
    {
        data.id = doc["id"].GetString();
    }

    if (doc.HasMember("Name") && doc["Name"].IsString())
    {
        data.Name = doc["Name"].GetString();
    }

    // 读取list数组
    if (doc.HasMember("list") && doc["list"].IsArray())
    {
        const rapidjson::Value &json_list = doc["list"];

        // 使用C++11迭代器遍历数组
        for (rapidjson::Value::ConstValueIterator it = json_list.Begin();
             it != json_list.End(); ++it)
        {
            const rapidjson::Value &item = *it;
            if (!item.IsObject())
                continue;

            EquipProperty prop;

            // 读取属性字段
            if (item.HasMember("type") && item["type"].IsString())
            {
                prop.type = item["type"].GetString();
            }

            // 读取addr数组
            if (item.HasMember("addr") && item["addr"].IsArray())
            {
                const rapidjson::Value &json_addr = item["addr"];
                for (rapidjson::Value::ConstValueIterator addr_it = json_addr.Begin();
                     addr_it != json_addr.End(); ++addr_it)
                {
                    if (addr_it->IsInt())
                    {
                        prop.addr.push_back(addr_it->GetInt());
                    }
                }
            }

            // 注意：JSON中是name_cn，结构体中是ame_cn（处理拼写差异）
            if (item.HasMember("name_cn") && item["name_cn"].IsString())
            {
                prop.name_cn = item["name_cn"].GetString();
            }

            if (item.HasMember("name_en") && item["name_en"].IsString())
            {
                prop.name_en = item["name_en"].GetString();
            }

            if (item.HasMember("len") && item["len"].IsInt())
            {
                prop.len = item["len"].GetInt();
            }

            if (item.HasMember("reg") && item["reg"].IsString())
            {
                prop.reg = item["reg"].GetString();
            }

            if (item.HasMember("comment") && item["comment"].IsString())
            {
                prop.comment = item["comment"].GetString();
            }

            // value字段在JSON中不存在，保持为空向量
            data.list.push_back(prop);
        }
    }

    return true;
}

bool CNodeDataCofing::write(const std::string &filename, const NodeData_Config &data)
{
    // 创建JSON文档
    rapidjson::Document doc;
    doc.SetObject();
    rapidjson::Document::AllocatorType &alloc = doc.GetAllocator();

    // 添加顶层字段
    doc.AddMember("equip", rapidjson::Value(data.equip.c_str(), alloc).Move(), alloc);
    doc.AddMember("type", rapidjson::Value(data.type.c_str(), alloc).Move(), alloc);
    doc.AddMember("id", rapidjson::Value(data.id.c_str(), alloc).Move(), alloc);
    doc.AddMember("Name", rapidjson::Value(data.Name.c_str(), alloc).Move(), alloc); // 注意JSON中的键是"Name"大写

    // 生成list数组
    rapidjson::Value json_list(rapidjson::kArrayType);
    for (auto it = data.list.begin();
         it != data.list.end(); ++it)
    { // C++11兼容的迭代方式
        rapidjson::Value json_prop(rapidjson::kObjectType);
        _generate_property(*it, json_prop, alloc);
        json_list.PushBack(json_prop, alloc);
    }
    doc.AddMember("list", json_list, alloc);

    // 写入文件
    std::ofstream ofs(filename);
    if (!ofs.is_open())
    {
        // std::cerr << "无法打开文件进行写入: " << filename << std::endl;
        ES_LOG(TAG, LEVEL_ERROR, "Fails to write to json_file: %s", filename.c_str());
        return false;
    }

    rapidjson::OStreamWrapper osw(ofs);
    rapidjson::Writer<rapidjson::OStreamWrapper> writer(osw);
    doc.Accept(writer);

    return true;
}

// 解析单个属性项（EquipProperty）
void CNodeDataCofing::_parse_property(const rapidjson::Value &json_prop, EquipProperty &prop)
{
    // 读取字符串字段
    if (json_prop.HasMember("type") && json_prop["type"].IsString())
        prop.type = json_prop["type"].GetString();

    if (json_prop.HasMember("ame_cn") && json_prop["ame_cn"].IsString())
        prop.name_cn = json_prop["ame_cn"].GetString();

    if (json_prop.HasMember("name_en") && json_prop["name_en"].IsString())
        prop.name_en = json_prop["name_en"].GetString();

    if (json_prop.HasMember("len") && json_prop["len"].IsString())
        prop.len = json_prop["len"].GetInt();

    if (json_prop.HasMember("reg") && json_prop["reg"].IsString())
        prop.reg = json_prop["reg"].GetString();

    if (json_prop.HasMember("comment") && json_prop["comment"].IsString())
        prop.comment = json_prop["comment"].GetString();

    // 特殊处理 addr：可能是字符串或数组
    if (json_prop.HasMember("addr"))
    {
        const auto &json_addr = json_prop["addr"];
        if (json_addr.IsArray())
        { // 数组形式（如[76,78,80]）
            for (const auto &item : json_addr.GetArray())
            {
                if (item.IsInt())
                {
                    prop.addr.push_back(item.GetInt());
                }
            }
        }
        else if (json_addr.IsString())
        { // 字符串形式（如"66"）
            std::string addr_str = json_addr.GetString();
            if (!addr_str.empty())
            {
                // 尝试将字符串转换为整数（处理空字符串情况）
                try
                {
                    prop.addr.push_back(std::stoi(addr_str));
                }
                catch (...)
                {
                    // 转换失败则忽略（如空字符串）
                }
            }
        }
    }
}

// 生成单个属性项到JSON
void CNodeDataCofing::_generate_property(const EquipProperty &prop, rapidjson::Value &json_prop, rapidjson::Document::AllocatorType &alloc)
{
    json_prop.SetObject();

    // 添加字符串字段
    json_prop.AddMember("type", rapidjson::Value(prop.type.c_str(), alloc).Move(), alloc);
    json_prop.AddMember("ame_cn", rapidjson::Value(prop.name_cn.c_str(), alloc).Move(), alloc);
    json_prop.AddMember("name_en", rapidjson::Value(prop.name_en.c_str(), alloc).Move(), alloc);
    json_prop.AddMember("len", rapidjson::Value(prop.len).Move(), alloc);
    json_prop.AddMember("reg", rapidjson::Value(prop.reg.c_str(), alloc).Move(), alloc);
    json_prop.AddMember("comment", rapidjson::Value(prop.comment.c_str(), alloc).Move(), alloc);

    // 处理 addr（数组形式）
    rapidjson::Value json_addr(rapidjson::kArrayType);
    for (int addr : prop.addr)
    {
        json_addr.PushBack(addr, alloc);
    }
    json_prop.AddMember("addr", json_addr, alloc);
}
